home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Muzyka / Edytory sampli (probek dzwieku) / ZynAddSubFX_2.2.0 / Setup_ZynAddSubFX-2.2.0.exe / source code / Synth / SUBnote.C < prev    next >
C/C++ Source or Header  |  2005-03-14  |  12KB  |  420 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   SUBnote.C - The "subtractive" synthesizer
  5.   Copyright (C) 2002-2005 Nasca Octavian Paul
  6.   Author: Nasca Octavian Paul
  7.  
  8.   This program is free software; you can redistribute it and/or modify
  9.   it under the terms of version 2 of the GNU General Public License 
  10.   as published by the Free Software Foundation.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License (version 2) for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License (version 2)
  18.   along with this program; if not, write to the Free Software Foundation,
  19.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20.  
  21. */
  22.  
  23. #include <math.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include "../globals.h"
  27. #include "SUBnote.h"
  28. #include "../Misc/Util.h"
  29.  
  30. SUBnote::SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote){
  31.     ready=0;
  32.     
  33.     tmpsmp=new REALTYPE[SOUND_BUFFER_SIZE];
  34.     tmprnd=new REALTYPE[SOUND_BUFFER_SIZE];
  35.     
  36.     pars=parameters;
  37.     ctl=ctl_;
  38.     portamento=portamento_;
  39.     NoteEnabled=ON;
  40.     volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB
  41.     volume*=VelF(velocity,pars->PAmpVelocityScaleFunction);
  42.     if (pars->PPanning!=0) panning=pars->PPanning/127.0;
  43.     else panning=RND;
  44.     numstages=pars->Pnumstages;
  45.     stereo=pars->Pstereo;
  46.     start=pars->Pstart;
  47.     firsttick=1;
  48.     int pos[MAX_SUB_HARMONICS];
  49.  
  50.     if (pars->Pfixedfreq==0) basefreq=freq;
  51.     else {
  52.         basefreq=440.0;
  53.         int fixedfreqET=pars->PfixedfreqET;
  54.         if (fixedfreqET!=0) {//if the frequency varies according the keyboard note 
  55.         REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0);
  56.         if (fixedfreqET<=64) basefreq*=pow(2.0,tmp);
  57.             else basefreq*=pow(3.0,tmp);
  58.         };
  59.  
  60.     };
  61.     REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune);
  62.     basefreq*=pow(2.0,detune/1200.0);//detune
  63. //    basefreq*=ctl->pitchwheel.relfreq;//pitch wheel
  64.     
  65.     //global filter    
  66.     GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq 
  67.                         (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing
  68.             (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1);
  69.  
  70.     GlobalFilterL=NULL;GlobalFilterR=NULL;
  71.     GlobalFilterEnvelope=NULL;
  72.  
  73.     //select only harmonics that desire to compute    
  74.     numharmonics=0;
  75.     for (int n=0;n<MAX_SUB_HARMONICS;n++){
  76.     if (pars->Phmag[n]==0)continue;
  77.     if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq
  78.     pos[numharmonics++]=n;
  79.     };
  80.     
  81.     if (numharmonics==0) {
  82.     NoteEnabled=OFF;
  83.     return;
  84.     };
  85.         
  86.     
  87.     lfilter=new bpfilter[numstages*numharmonics];
  88.     if (stereo!=0) rfilter=new bpfilter[numstages*numharmonics];
  89.     
  90.     //how much the amplitude is normalised (because the harmonics)
  91.     REALTYPE reduceamp=0.0;
  92.     
  93.     for (int n=0;n<numharmonics;n++){
  94.  
  95.     REALTYPE freq=basefreq*(pos[n]+1);
  96.     
  97.     //the bandwidth is not absolute(Hz); it is relative to frequency
  98.     REALTYPE bw=pow(10,(pars->Pbandwidth-127.0)/127.0*4)*numstages;
  99.  
  100.     //Bandwidth Scale
  101.     bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0);
  102.  
  103.     //Relative BandWidth    
  104.     bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0);
  105.  
  106.     if (bw>25.0) bw=25.0;
  107.  
  108.     //try to keep same amplitude on all freqs and bw. (empirically)
  109.     REALTYPE gain=sqrt(1500.0/(bw*freq));
  110.  
  111.         REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0;
  112.     REALTYPE hgain;
  113.  
  114.         switch(pars->Phmagtype){
  115.         case 1:hgain=exp(hmagnew*log(0.01)); break;
  116.         case 2:hgain=exp(hmagnew*log(0.001));break;
  117.         case 3:hgain=exp(hmagnew*log(0.0001));break;
  118.         case 4:hgain=exp(hmagnew*log(0.00001));break;
  119.         default:hgain=1.0-hmagnew;
  120.     };
  121.     gain*=hgain;
  122.         reduceamp+=hgain;
  123.  
  124.         for (int nph=0;nph<numstages;nph++){
  125.         REALTYPE amp=1.0;
  126.             if (nph==0) amp=gain;
  127.         initfilter(lfilter[nph+n*numstages],freq,bw,amp,hgain);
  128.         if (stereo!=0) initfilter(rfilter[nph+n*numstages],freq,bw,amp,hgain);
  129.     };
  130.     };
  131.     
  132.     if (reduceamp<0.001) reduceamp=1.0;
  133.     volume/=reduceamp;
  134.     
  135.     oldpitchwheel=0;
  136.     oldbandwidth=64;
  137.     if (pars->Pfixedfreq==0) initparameters(basefreq);
  138.     else initparameters(basefreq/440.0*freq);
  139.  
  140.     oldamplitude=newamplitude;
  141.     ready=1;
  142. };
  143.  
  144. SUBnote::~SUBnote(){
  145.     if (NoteEnabled!=OFF) KillNote();
  146.     delete [] tmpsmp;
  147.     delete [] tmprnd;
  148. };
  149.  
  150. /*
  151.  * Kill the note
  152.  */
  153. void SUBnote::KillNote(){
  154.     if (NoteEnabled!=OFF){
  155.     delete [] lfilter;
  156.     lfilter=NULL;
  157.     if (stereo!=0) delete [] rfilter;
  158.     rfilter=NULL;
  159.     delete(AmpEnvelope);
  160.     if (FreqEnvelope!=NULL) delete(FreqEnvelope);
  161.     if (BandWidthEnvelope!=NULL) delete(BandWidthEnvelope);
  162.     NoteEnabled=OFF;
  163.     };
  164.     
  165. };
  166.  
  167.  
  168. /*
  169.  * Compute the filters coefficients
  170.  */
  171. void SUBnote::computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain){
  172.     if (freq>SAMPLE_RATE/2.0-200.0) {
  173.     freq=SAMPLE_RATE/2.0-200.0;
  174.     };
  175.  
  176.     REALTYPE omega=2.0*PI*freq/SAMPLE_RATE;
  177.     REALTYPE sn=sin(omega);REALTYPE cs=cos(omega);
  178.     REALTYPE alpha=sn*sinh(LOG_2/2.0*bw*omega/sn);
  179.  
  180.     if (alpha>1) alpha=1;
  181.     if (alpha>bw) alpha=bw;
  182.     
  183.     filter.b0=alpha/(1.0+alpha)*filter.amp*gain;
  184.     filter.b2=-alpha/(1.0+alpha)*filter.amp*gain;
  185.     filter.a1=-2.0*cs/(1.0+alpha); 
  186.     filter.a2=(1.0-alpha)/(1.0+alpha);
  187.  
  188. };
  189.  
  190.  
  191. /*
  192.  * Initialise the filters
  193.  */
  194. void SUBnote::initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag){
  195.     filter.xn1=0.0;filter.xn2=0.0;
  196.     
  197.     if (start==0) {
  198.     filter.yn1=0.0;
  199.     filter.yn2=0.0;
  200.     } else {
  201.     REALTYPE a=0.1*mag;//empirically
  202.         REALTYPE p=RND*2.0*PI;
  203.     if (start==1) a*=RND;
  204.     filter.yn1=a*cos(p);
  205.     filter.yn2=a*cos(p+freq*2.0*PI/SAMPLE_RATE);
  206.  
  207.     //correct the error of computation the start amplitude 
  208.     //at very high frequencies    
  209.     if (freq>SAMPLE_RATE*0.96) {
  210.         filter.yn1=0.0;
  211.         filter.yn2=0.0;
  212.     
  213.     };
  214.     };
  215.  
  216.     filter.amp=amp;   
  217.     filter.freq=freq;
  218.     filter.bw=bw;
  219.     computefiltercoefs(filter,freq,bw,1.0);
  220. };
  221.  
  222. /*
  223.  * Do the filtering
  224.  */
  225. void SUBnote::filter(bpfilter &filter,REALTYPE *smps){
  226.     int i;
  227.     REALTYPE out;
  228.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  229.        out=smps[i] * filter.b0 + filter.b2 * filter.xn2
  230.           -filter.a1 * filter.yn1 - filter.a2 * filter.yn2;
  231.        filter.xn2=filter.xn1;
  232.        filter.xn1=smps[i];
  233.        filter.yn2=filter.yn1;
  234.        filter.yn1=out;
  235.        smps[i]=out;
  236.  
  237.     };
  238. };
  239.  
  240. /*
  241.  * Init Parameters
  242.  */
  243. void SUBnote::initparameters(REALTYPE freq){
  244.     AmpEnvelope=new Envelope(pars->AmpEnvelope,freq);
  245.     if (pars->PFreqEnvelopeEnabled!=0) FreqEnvelope=new Envelope(pars->FreqEnvelope,freq);
  246.         else FreqEnvelope=NULL;
  247.     if (pars->PBandWidthEnvelopeEnabled!=0) BandWidthEnvelope=new Envelope(pars->BandWidthEnvelope,freq);
  248.         else BandWidthEnvelope=NULL;
  249.     if (pars->PGlobalFilterEnabled!=0){
  250.     globalfiltercenterq=pars->GlobalFilter->getq();
  251.     GlobalFilterL=new Filter(pars->GlobalFilter);
  252.     if (stereo!=0) GlobalFilterR=new Filter(pars->GlobalFilter);
  253.     GlobalFilterEnvelope=new Envelope(pars->GlobalFilterEnvelope,freq);
  254.     GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq);
  255.     };
  256.     computecurrentparameters();
  257. };
  258.  
  259.  
  260. /*
  261.  * Compute Parameters of SUBnote for each tick
  262.  */
  263. void SUBnote::computecurrentparameters(){
  264.     if ((FreqEnvelope!=NULL)||(BandWidthEnvelope!=NULL)||
  265.     (oldpitchwheel!=ctl->pitchwheel.data)||
  266.     (oldbandwidth!=ctl->bandwidth.data)||
  267.     (portamento!=0)){
  268.     REALTYPE envfreq=1.0;
  269.     REALTYPE envbw=1.0;
  270.     REALTYPE gain=1.0;
  271.         
  272.     if (FreqEnvelope!=NULL) {
  273.         envfreq=FreqEnvelope->envout()/1200;
  274.         envfreq=pow(2.0,envfreq);
  275.     };
  276.     envfreq*=ctl->pitchwheel.relfreq;//pitch wheel
  277.     if (portamento!=0) {//portamento is used
  278.         envfreq*=ctl->portamento.freqrap;
  279.         if (ctl->portamento.used==0){//the portamento has finished
  280.         portamento=0;//this note is no longer "portamented"
  281.         };
  282.     };
  283.     
  284.     if (BandWidthEnvelope!=NULL) {
  285.         envbw=BandWidthEnvelope->envout();
  286.         envbw=pow(2,envbw);        
  287.     };
  288.     envbw*=ctl->bandwidth.relbw;//bandwidth controller
  289.  
  290.     REALTYPE tmpgain=1.0/sqrt(envbw*envfreq);
  291.  
  292.     for (int n=0;n<numharmonics;n++){
  293.         for (int nph=0;nph<numstages;nph++) {
  294.         if (nph==0) gain=tmpgain;else gain=1.0;
  295.             computefiltercoefs( lfilter[nph+n*numstages],
  296.                         lfilter[nph+n*numstages].freq*envfreq,
  297.                     lfilter[nph+n*numstages].bw*envbw,gain);
  298.         };
  299.     };
  300.     if (stereo!=0)
  301.     for (int n=0;n<numharmonics;n++){
  302.         for (int nph=0;nph<numstages;nph++) {
  303.         if (nph==0) gain=tmpgain;else gain=1.0;
  304.             computefiltercoefs( rfilter[nph+n*numstages],
  305.                         rfilter[nph+n*numstages].freq*envfreq,
  306.                     rfilter[nph+n*numstages].bw*envbw,gain);
  307.         };
  308.     };
  309.     oldbandwidth=ctl->bandwidth.data;
  310.     oldpitchwheel=ctl->pitchwheel.data;
  311.     };
  312.     newamplitude=volume*AmpEnvelope->envout_dB()*2.0;
  313.     
  314.     //Filter
  315.     if (GlobalFilterL!=NULL){
  316.     REALTYPE globalfilterpitch=GlobalFilterCenterPitch+GlobalFilterEnvelope->envout();
  317.     REALTYPE filterfreq=globalfilterpitch+ctl->filtercutoff.relfreq+GlobalFilterFreqTracking;
  318.     filterfreq=GlobalFilterL->getrealfreq(filterfreq);
  319.     
  320.     GlobalFilterL->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq);
  321.     if (GlobalFilterR!=NULL) GlobalFilterR->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq);
  322.     };
  323.  
  324. };
  325.  
  326. /*
  327.  * Note Output
  328.  */
  329. int SUBnote::noteout(REALTYPE *outl,REALTYPE *outr){
  330.     int i;
  331.  
  332.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  333.     outl[i]=denormalkillbuf[i];
  334.     outr[i]=denormalkillbuf[i];
  335.     };
  336.     
  337.     if (NoteEnabled==OFF) return(0);
  338.  
  339.     //left channel
  340.     for (i=0;i<SOUND_BUFFER_SIZE;i++) tmprnd[i]=RND*2.0-1.0;
  341.     for (int n=0;n<numharmonics;n++){
  342.     for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpsmp[i]=tmprnd[i];
  343.     for (int nph=0;nph<numstages;nph++) 
  344.          filter(lfilter[nph+n*numstages],tmpsmp);     
  345.     for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=tmpsmp[i];
  346.     };
  347.  
  348.     if (GlobalFilterL!=NULL) GlobalFilterL->filterout(&outl[0]);     
  349.     
  350.     //right channel
  351.     if (stereo!=0){
  352.     for (i=0;i<SOUND_BUFFER_SIZE;i++) tmprnd[i]=RND*2.0-1.0;
  353.     for (int n=0;n<numharmonics;n++){
  354.         for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpsmp[i]=tmprnd[i];
  355.         for (int nph=0;nph<numstages;nph++) 
  356.             filter(rfilter[nph+n*numstages],tmpsmp);     
  357.         for (i=0;i<SOUND_BUFFER_SIZE;i++) outr[i]+=tmpsmp[i];
  358.     };
  359.     if (GlobalFilterR!=NULL) GlobalFilterR->filterout(&outr[0]);     
  360.     } else for (i=0;i<SOUND_BUFFER_SIZE;i++) outr[i]=outl[i];
  361.     
  362.     if (firsttick!=0){
  363.     int n=10;if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE;
  364.     for (i=0;i<n;i++) {
  365.         REALTYPE ampfadein=0.5-0.5*cos((REALTYPE) i/(REALTYPE) n*PI);
  366.         outl[i]*=ampfadein;
  367.         outr[i]*=ampfadein;
  368.     };
  369.     firsttick=0;
  370.     };
  371.  
  372.     if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude,newamplitude)){
  373.     // Amplitude interpolation 
  374.         for (i=0;i<SOUND_BUFFER_SIZE;i++){
  375.        REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(oldamplitude
  376.               ,newamplitude,i,SOUND_BUFFER_SIZE);
  377.        outl[i]*=tmpvol*panning; 
  378.        outr[i]*=tmpvol*(1.0-panning);
  379.         };
  380.     } else {
  381.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  382.         outl[i]*=newamplitude*panning;
  383.         outr[i]*=newamplitude*(1.0-panning);
  384.     };
  385.     };
  386.  
  387.     oldamplitude=newamplitude;    
  388.     computecurrentparameters();
  389.     
  390.     // Check if the note needs to be computed more
  391.     if (AmpEnvelope->finished()!=0){
  392.         for (i=0;i<SOUND_BUFFER_SIZE;i++) {//fade-out
  393.         REALTYPE tmp=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE;
  394.         outl[i]*=tmp;
  395.         outr[i]*=tmp;
  396.         };
  397.     KillNote();    
  398.     };
  399.     return(1);
  400. };
  401.  
  402. /*
  403.  * Relase Key (Note Off)
  404.  */
  405. void SUBnote::relasekey(){
  406.     AmpEnvelope->relasekey();
  407.     if (FreqEnvelope!=NULL) FreqEnvelope->relasekey();
  408.     if (BandWidthEnvelope!=NULL) BandWidthEnvelope->relasekey();
  409.     if (GlobalFilterEnvelope!=NULL) GlobalFilterEnvelope->relasekey();
  410. };
  411.  
  412. /*
  413.  * Check if the note is finished
  414.  */
  415. int SUBnote::finished(){
  416.   if (NoteEnabled==OFF) return(1);
  417.     else return(0);    
  418. };
  419.  
  420.